<?php

# 锁
    # 计算机协调多个进程或线程并发访问同一资源的机制

# 锁分类
    # 性能
        # 乐观锁（用版本对比实现）
        # 悲观锁（可能出现阻塞状态）
    # 对数据库操作类型（悲观锁）
        # 读锁（共享锁 S）：当前操作完成之前，阻塞其他写锁，不阻塞其他读锁
        # 写锁（排他锁 X）：当前操作完成之前，阻塞其他写锁和读锁
    # 对数据库操作粒度
        # 行锁（偏向于读锁）：开销小、加锁快、无死锁、锁定粒度大、冲突概率高、并发度最低
        # 表锁（偏向于写锁）：开销大、加锁慢、有死锁、锁定粒度小、冲突概率低、并发度最高

# 加锁
    # 显式S锁：SQL语句 lock in share mode
    # 显式X锁：SQL语句 for update
    # 隐式X锁：insert、delete、update操作




/**
 * 特点：

　　表锁偏向MyISAM存储引擎。

案例分析(加读锁）

　　当前session和其他session都可以读该表

　　当前session中插入或者更新锁定的表都会报错，其他session插入或更新则会等待

案例分析(加写锁）

　　当前session对该表的增删改查都没有问题，其他session对该表的所有操作被阻塞

案例结论

MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行增删改操作前,会自动给涉及的表加写锁。

　　1、对MyISAM表的读操作(加读锁) ,不会阻寒其他进程对同一表的读请求,但会阻赛对同一表的写请求。只有当读锁释放后,才会执行其它进程的写操作。

　　2、对MylSAM表的写操作(加写锁) ,会阻塞其他进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作
 *
行锁（偏向于写锁）

特点：

　　行锁偏向InnoDB存储引擎，InnoDB与MYISAM的最大不同有两点：一是支持事务（TRANSACTION）；二是采用了行级锁；并且行锁支持事务处理。

在行锁进行并发事务处理时，会带来一下问题：

更新丢失（Lost Update）

　　当两个或多个事务选择同一行，然后基于最初选定的值更新该行时，由于每个事务都不知道其他事务的存在，就会发生丢失更新问题–最后的更新覆盖了由其他事务所做的更新。

脏读（Dirty Reads）

　　一个事务正在对一条记录做修改，在这个事务完成并提交前，这条记录的数据就处于不一致的状态；这时，另一个事务也来读取同一条记录，如果不加控制，第二个事务读取了这些“脏”数据，并据此作进一步的处理，就会产生未提交的数据依赖关系。这种现象被形象的叫做“脏读”。

　　一句话：事务A读取到了事务B已经修改但尚未提交的数据，还在这个数据基础上做了操作。此时，如果B事务回滚，A读取的数据无效，不符合一致性要求。

不可重读（Non-Repeatable Reads）

　　一个事务在读取某些数据后的某个时间，再次读取以前读过的数据，却发现其读出的数据已经发生了改变、或某些记录已经被删除了！这种现象就叫做“不可重复读”。

　　一句话：事务A读取到了事务B已经提交的修改数据，不符合隔离性

幻读（Phantom Reads）

　　一个事务按相同的查询条件重新读取以前检索过的数据，却发现其他事务插入了满足其查询条件的新数据，这种现象就称为“幻读”。

　　一句话：事务A读取到了事务B提交的新增数据，不符合隔离性

脏读是事务B里面修改了数据
 *
 */

# 死锁
    # 两个或多个锁，互相等待对方解锁